/**
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.steamcrafted.materialiconlib;

import net.steamcrafted.materialiconlib.factory.PixelMapFactory;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.render.PixelMapHolder;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;

public abstract class BaseMaterialIconView extends Component implements Component.DrawTask {

    private static final String ATTRIBUTE_ICON_COLOR = "miv_icon_color";

    private static final String ATTRIBUTE_BG_COLOR = "miv_bg_color";

    private static final String ATTRIBUTE_PADDING = "miv_padding";

    private static final String ATTRIBUTE_IMG_SRC = "miv_img_src";

    private static final String ATTRIBUTE_RADIUS = "miv_radius";

    private static final String ATTRIBUTE_IS_CIRCULAR = "miv_circular";

    protected int mResId;
    protected int mIconColor;
    protected int mBackgroundColor;
    protected int mRadius;
    protected int mPadding;
    protected int mWidth;
    protected int mHeight;
    protected int lengthOfSide_icon;

    protected boolean isCircular = false;

    private Paint mPaint;

    public BaseMaterialIconView(Context context) {
        super(context);
        init(null);
    }

    public BaseMaterialIconView(Context context, AttrSet attrSet) {
        super(context, attrSet);
        init(attrSet);
    }

    public BaseMaterialIconView(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        init(attrSet);
    }

    public BaseMaterialIconView(Context context, AttrSet attrSet, int resId) {
        super(context, attrSet, resId);
        init(attrSet);
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        if (getResId()==0)return;
        if (get_Width()==0||get_Height()==0){
            mWidth = getWidth();
            mHeight = getHeight();
        }
        if (get_Width() != get_Height()){
            mWidth = Math.min(get_Width(), get_Height());
            mHeight = mWidth;
        }
        if (get_Padding()==0){
            mPadding = getPadding()[0];
        }
        lengthOfSide_icon = get_Width()-2*get_Padding();
        mRadius = isCircular() ? get_Width()/2 : Math.min(get_Width()/2 , getRadius());
        Path path = new Path();
        path.addRoundRect(new RectFloat(0, 0, get_Width(), get_Height()), getRadius(), getRadius(), Path.Direction.CLOCK_WISE);
        canvas.clipPath(path, Canvas.ClipOp.INTERSECT);
        canvas.drawColor(getBackgroundColor(), Canvas.PorterDuffMode.SRC);
        PixelMapHolder mapHolder = new PixelMapHolder(PixelMapFactory.CreatePixelMap(getContext(), getResId(), getIconColor(), lengthOfSide_icon, lengthOfSide_icon));
        canvas.drawPixelMapHolder(mapHolder, get_Padding(),get_Padding(), mPaint);
    }

    protected void init(AttrSet attrSet){
        if (attrSet!=null){
            boolean present = attrSet.getAttr(ATTRIBUTE_IMG_SRC).isPresent();
            mResId = present ? toIntegerValue(attrSet.getAttr(ATTRIBUTE_IMG_SRC).get().getStringValue()) : getResId();
            present = attrSet.getAttr(ATTRIBUTE_ICON_COLOR).isPresent();
            mIconColor = present ? attrSet.getAttr(ATTRIBUTE_ICON_COLOR).get().getColorValue().getValue() : getIconColor()==0 ? 0xFFFFFFFF : getIconColor();
            present = attrSet.getAttr(ATTRIBUTE_BG_COLOR).isPresent();
            mBackgroundColor = present ? attrSet.getAttr(ATTRIBUTE_BG_COLOR).get().getColorValue().getValue() : getBackgroundColor();
            present = attrSet.getAttr(ATTRIBUTE_RADIUS).isPresent();
            mRadius = present ? attrSet.getAttr(ATTRIBUTE_RADIUS).get().getDimensionValue() : getRadius();
            present = attrSet.getAttr(ATTRIBUTE_IS_CIRCULAR).isPresent();
            isCircular = present ? attrSet.getAttr(ATTRIBUTE_IS_CIRCULAR).get().getBoolValue() : isCircular();
            present = attrSet.getAttr(ATTRIBUTE_PADDING).isPresent();
            mPadding = present ? attrSet.getAttr(ATTRIBUTE_PADDING).get().getDimensionValue() : get_Padding();
        }else {
            mResId = getResId();
            mIconColor = getIconColor()==0 ? 0xFFFFFFFF : getIconColor();
            mBackgroundColor = getBackgroundColor();
            mRadius = getRadius();
            mPadding = get_Padding();
        }
        mWidth = get_Width();
        mHeight = get_Height();
        isCircular = isCircular();
        mPaint = new Paint();
        mPaint.setDither(true);
        mPaint.setAntiAlias(true);
        addDrawTask(this);
    }

    private int toIntegerValue(String res){
        try {
            if (res==null)return 0;
            int index = res.indexOf(':')+1;
            String value = res.substring(index);
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    public abstract int getResId();

    public abstract int getIconColor();

    public abstract int getBackgroundColor();

    public abstract int getRadius();

    public abstract int get_Padding();

    public abstract int get_Width();

    public abstract int get_Height();

    public boolean isCircular() {
        return isCircular;
    }

    public BaseMaterialIconView set_CircularComponent(boolean circularComponent) {
        isCircular = circularComponent;
        return this;
    }

    public BaseMaterialIconView set_ResId(int mResId) {
        this.mResId = mResId;
        return this;
    }

    public BaseMaterialIconView set_backgroundColor(int mBackgroundColor) {
        this.mBackgroundColor = mBackgroundColor;
        return this;
    }

    public BaseMaterialIconView set_iconColor(int mIconColor) {
        this.mIconColor = mIconColor;
        return this;
    }

    public BaseMaterialIconView set_padding(int padding){
        this.mPadding = padding;
        return this;
    }

    public BaseMaterialIconView set_radius(int radius){
        this.mRadius = radius;
        return this;
    }

    public BaseMaterialIconView setSize(int size){
        this.mWidth = mHeight = size;
        return this;
    }
}
